﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SharpDiary.Core.Utility;
using SharpDiary.Core.Common;
using SharpDiary.Core.Security;
using SharpDiary.Core.ORMapping;
using SharpDiary.Core.Data;
using System.Data.Common;

namespace SharpDiary.Diary
{
    public partial class DiaryViewerList : UserControl
    {
        private string _lastKeyword = string.Empty; //上一次搜索的关键字


        public event EventHandler<CountChangedEventArgs> CountChanged;

        protected virtual void OnCountChanged(object sender, CountChangedEventArgs e)
        {
            if (CountChanged != null)
            {
                CountChanged(sender, e);
            }
        }

        public event EventHandler<SelectedEventArgs> Selected;

        protected virtual void OnSelected(object sender, SelectedEventArgs e)
        {
            if (Selected != null)
            {
                Selected(sender, e);
            }
        }

        public DiaryViewerList()
        {
            InitializeComponent();

            ResizeRedraw = true;
            DoubleBuffered = true;
        }

        private string _keyword = string.Empty;

        public string Keyword
        {
            get { return _keyword; }
            set { _keyword = value; }
        }

        /// <summary>
        /// 获取日记总数。
        /// </summary>
        /// <returns></returns>
        private int GetDiaryCount(string keyWord)
        {
            StringBuilder sql = new StringBuilder();
            sql.AppendLine("select count(*) as FCount from Diary");

            //按关键字筛选
            if (!string.IsNullOrEmpty(keyWord))
            {
                sql.AppendLine("where content like @content or Title like @title");
            }

            DataAccessService das = Utils.GetDataAccessServiceInstance();
            object result = das.ExecuteScalar(sql.ToString(),
                CommandType.Text,
                new DbParameter[]{
                    das.CreateParameter("@content", DbType.String, "%" + keyWord + "%"),
                    das.CreateParameter("@title", DbType.String, "%" + keyWord + "%")
                });

            return Convert.ToInt32(result);
        }

        /// <summary>
        /// 显示所有日记。
        /// </summary>
        /// <param name="forceSearch">是否强制执行搜索操作</param>
        /// <param name="keyWord">按此关键字筛选</param>
        public int Build(string keyWord, string filter, bool forceSearch, bool readOnly)
        {
            if (keyWord == null) { return 0; }

            int result = 0;
            _keyword = keyWord;

            if (!forceSearch)
            {
                //如果此次搜索的关键字与上一次相同，则不搜索。
                if (keyWord.Equals(_lastKeyword, StringComparison.CurrentCultureIgnoreCase))
                {
                    return 0;
                }
            }

            _lastKeyword = keyWord;

            StringBuilder sql = new StringBuilder();
            sql.AppendLine("select * from Diary where 1=1");

            if (!string.IsNullOrEmpty(filter))
            {
                sql.AppendLine(filter);
            }

            //按关键字筛选
            if (!string.IsNullOrEmpty(keyWord))
            {
                sql.AppendLine("and content like @content or Title like @title");
            }

            sql.AppendLine("order by CreatedDatetime ASC");

            DataAccessService das = Utils.GetDataAccessServiceInstance();
            List<DiaryInfo> diaries = DbObjectMappingHelper.QueryObjectList<DiaryInfo>(
                sql.ToString(),
                new DbParameter[]{
                    das.CreateParameter("@content", DbType.String, "%" + keyWord + "%"),
                    das.CreateParameter("@title", DbType.String, "%" + keyWord + "%")
                });
            result = diaries.Count;

            pnlMain.SuspendLayout();
            try
            {
                pnlMain.Controls.Clear();

                foreach (DiaryInfo diary in diaries)
                {
                    DiaryViewer diaryView = new DiaryViewer();
                    diaryView.Diary = diary;
                    diaryView.Parent = pnlMain;
                    //diaryView.Size = pnlMain.ClientSize;
                    diaryView.Dock = DockStyle.Top;
                    diaryView.ReadOnly = readOnly;

                    diaryView.Saved += new EventHandler<SavedEventArgs>(Diary_Saved);
                    diaryView.Removed += new EventHandler<RemovedEventArgs>(diaryView_Removed);
                    diaryView.Selected += new EventHandler<SelectedEventArgs>(diaryView_Selected);

                    pnlMain.Controls.Add(diaryView);
                }
            }
            finally
            {
                pnlMain.ResumeLayout();
            }

            CountChangedEventArgs args = new CountChangedEventArgs();
            args.Count = GetDiaryCount(Keyword);

            OnCountChanged(this, args);

            return result;
        }

        private void diaryView_Selected(object sender, SelectedEventArgs e)
        {
            pnlMain.ScrollControlIntoView(e.SelectedDiaryViewer);
            OnSelected(this, e);
        }

        private void diaryView_Removed(object sender, RemovedEventArgs e)
        {
            CountChangedEventArgs args = new CountChangedEventArgs();
            args.Count = GetDiaryCount(Keyword);

            OnCountChanged(this, args);
        }

        /// <summary>
        /// 显示所有日记。
        /// </summary>
        public void Build(bool readOnly)
        {
            Build(string.Empty, string.Empty, true, readOnly);
        }

        /// <summary>
        /// 新建日记。
        /// </summary>
        public void NewDiary()
        {
            DiaryViewer newDiary = new DiaryViewer();
            newDiary.Parent = pnlMain;
            //newDiary.Size = pnlMain.ClientSize;
            newDiary.Dock = DockStyle.Top;
            newDiary.Saved += new EventHandler<SavedEventArgs>(Diary_Saved);
            newDiary.Removed += new EventHandler<RemovedEventArgs>(diaryView_Removed);

            pnlMain.Controls.Add(newDiary);
            newDiary.Top = 0;

            pnlMain.ScrollControlIntoView(newDiary);
            newDiary.Focus();
        }

        private void Diary_Saved(object sender, SavedEventArgs e)
        {
            if (e.Action == SavingAction.Created)
            {
                CountChangedEventArgs args = new CountChangedEventArgs();
                args.Count = GetDiaryCount(Keyword);

                OnCountChanged(this, args);
            }
        }
    }

    public class CountChangedEventArgs : EventArgs
    {
        private int _count = 0;

        public int Count
        {
            get { return _count; }
            set { _count = value; }
        }

        public CountChangedEventArgs() { }
    }
}
